import { taskType } from "../../enum"
import { objIDToObj, roomNameToObj } from "../../tools/baseTools"

const taskManager = {
    init: (params) => {
        let { room, roomName, owner } = params
        room.memory['task'] = {}
        let taskListMemory = room.memory['task']['taskType'] = {}
        let taskDetaMemory = room.memory['task']['taskDeta'] = {}
        Object.keys(taskType).map(type => { taskListMemory[type] = [] })
    },
    addTask({ taskID, taskType, publisherID, roomName = null, taskParams = {}, isUrgent = false }) {
        taskID = "第" + Game.time + "Tick: " + taskID
        if (!roomName) roomName = Game.getTaskByID(publisherID).pos.roomName
        // 检查任务ID是否已存在于任务管理器中        
        if (!Game.rooms[roomName]) {
            console.log(`${Date()} :addTask方法入参出现异常,roomName传错`);
            return null
        }
        let taskDeta = {
            taskID: taskID,
            taskType: taskType,
            publisherID: publisherID,
            roomName: roomName,
            holderID: null,
            doing: false,
            taskParams: taskParams
        }
        Memory.rooms[roomName]['task']['taskDeta'][taskID] = taskDeta
        // 根据是否紧急任务进行插队处理任务事务类型管理器注册任务
        isUrgent ? Memory.rooms[roomName]['task']['taskType'][taskType].unshift(taskID) : Memory.rooms[roomName]['task']['taskType'][taskType].push(taskID)
        return taskID
    },
    getTaskByID(taskID, holderID, roomName = null, getTask = true) {
        let taskDeta = null
        if (!roomName) {
            Object.keys(Memory.rooms).map(roomName => {
                if (taskDeta != null) return
                taskDeta = Memory.rooms[roomName]['task']['taskDeta'][taskID]
                if (!taskDeta) console.log(holderID + '访问了一个不存在的taskDeta,takID为' + taskID);
                if (getTask && taskDeta) _getTask(taskDeta, holderID)
            })
        } else {
            taskDeta = Memory.rooms[roomName]['task']['taskDeta'][taskID]
            if (!taskDeta) console.log(holderID + '访问了一个不存在的taskDeta,takID为' + taskID);
            if (getTask && taskDeta) _getTask(taskDeta, holderID)
        }
        return taskDeta
    },
    getTaskByType(taskType, holderID, roomName, getTask = false) {
        let result = {}
        let taskTypeList = Memory.rooms[roomName]['task']['taskType'][taskType]
        let taskDetaList = Memory.rooms[roomName]['task']['taskDeta']
        result['count'] = taskTypeList.length
        if (taskTypeList.length == 0) return result
        let index = 0
        let taskID
        do {
            taskID = taskTypeList[index]
            if (!taskDetaList[taskID]) break
            if (!taskDetaList[taskID].doing) {
                if (getTask) _getTask(taskDetaList[taskID], holderID)
                result['taskDeta'] = taskDetaList[taskID]
                result['taskID'] = taskID
                break
            }
            index++
        } while (index < taskTypeList.length);
        return result
    },
    finishTask(taskID, roomName = null, params = {}) {
        const { obj = '' } = params
        if (taskID == null) console.log(`任务id为空,入参错误,无法完成${roomName ? roomName + '房间内的' : ''}由${obj.name ? obj.name : obj.id}执行的任务`);
        if (!roomName) {
            Object.keys(Memory.rooms).map(roomName => { _finishTask(taskID, roomName) })
        } else {
            _finishTask(taskID, roomName)
        }
    },
    /**对异常的任务单进行自检 */
    checkSelf(roomName) {
        let taskDetaList = Memory.rooms[roomName]['task']['taskDeta']
        let taskTypeList = Memory.rooms[roomName]['task']['taskType']
        // 清除存在任务详情，但不存在任务列表中的数据
        Object.keys(taskDetaList).map(taskID => {
            // console.log(JSON.stringify(taskDetaList[taskID].taskType));
            if (!taskTypeList[taskDetaList[taskID].taskType].includes(taskID)) {
                // console.log(`清除存在任务详情，但不存在任务列表中的数据` + taskID);
                delete taskDetaList[taskID]
            }
        })
        // 清除存在任务列表，但不存在任务详情中的数据
        Object.keys(taskTypeList).map(taskType => {
            let newTaskTypeList = []
            taskTypeList[taskType].forEach(taskID => {
                if (!taskDetaList[taskID]) {
                    // console.log(`清除存在任务列表，但不存在任务详情中的数据` + taskID);
                    return
                }
                newTaskTypeList.push(taskID)
            })
            newTaskTypeList = [...new Set(newTaskTypeList)]
            taskTypeList[taskType] = newTaskTypeList
        })
        // 检查所有建筑发布的任务是否存在
        Object.keys(Memory.rooms[roomName]['structure']).map(structureType => {
            Object.keys(Memory.rooms[roomName]['structure'][structureType]).map(id => {
                let objMemory = Memory.rooms[roomName]['structure'][structureType][id]
                if (objMemory.publishTask.length == 0) return
                let newTaskIDList = []
                objMemory.publishTask.map(taskID => {
                    if (!taskDetaList[taskID]) return
                    newTaskIDList.push(taskID)
                })
                newTaskIDList = [...new Set(newTaskIDList)]
                objMemory.publishTask = newTaskIDList
            })
        })
        // 检查房间发布的任务
        let roomTaskIDList = []
        Memory.rooms[roomName]['info']['publishTask'].map(taskID => {
            if (!taskDetaList[taskID]) return
            roomTaskIDList.push(taskID)
        })
        roomTaskIDList = [...new Set(roomTaskIDList)]
        Memory.rooms[roomName]['info']['publishTask'] = roomTaskIDList
    }
}
/**完成任务
 * 1. 删除任务表和任务详情表中的数据
 * 2. 当任务执行者是creep，则清空执当前挂载的任务
 */
function _finishTask(taskID, roomName) {
    // 删除任务表和任务详情表中的数据
    let taskDeta = Memory.rooms[roomName]['task']['taskDeta'][taskID]
    let taskList = Memory.rooms[roomName]['task']['taskType'][taskDeta.taskType]
    let index
    if (taskList.length != 0) {
        index = taskList.indexOf(taskID)
        if (index != -1) taskList.splice(index, 1)
    }
    // 当任务执行者是creep，则清空执当前挂载的任务
    if (taskDeta.holderID && !Game.getObjectById(taskDeta.holderID)) Game.creeps[taskDeta.holderID].memory['currentTaskID'] = null
    delete Memory.rooms[roomName]['task']['taskDeta'][taskID]
    // 获取发布者的内存数据，删除发布者挂载的数据
    let publishObj = Game.getObjectById(taskDeta.publisherID)
    let publishTaskMemory
    if (publishObj) {
        publishTaskMemory = Memory.rooms[publishObj.pos.roomName]['structure'][publishObj.structureType][taskDeta.publisherID]['publishTask']
    } else {
        // 不存在说明发布任务者是房间
        publishTaskMemory = Memory.rooms[taskDeta.roomName]['info']['publishTask']
    }
    // console.log('如果报错，查看一下推送的地方' + JSON.stringify(publishTaskMemory));
    index = publishTaskMemory.indexOf(taskID)
    if (index != -1) publishTaskMemory.splice(index, 1)
}
/**切换对应任务详情的执行状态，并将执行者的当前任务id切换为当前正在执行的任务 */
function _getTask(taskDeta, holderID, doing = true) {
    Object.assign(taskDeta, {
        holderID: holderID,
        doing: doing
    })
    // console.log('执行任务的creep名称' + JSON.stringify(holderID));
    // 当任务执行者是creep，将当前taskID挂载到creep上
    if (Game.creeps[holderID]) {
        // console.log(`creep获取任务:${taskDeta.taskID}`);
        Memory.creeps[holderID]['currentTaskID'] = taskDeta.taskID
        return
    }
    // console.log(`领取任务，将任务${taskDeta.taskID}挂载到${holderID}上`);
    if (holderID && !Game.getObjectById(holderID)) {
        console.log(`room挂载任务:${taskDeta.taskID}`);
        Memory.creeps[holderID]['currentTaskID'] = taskDeta.taskID
        return
    }
}
// #region 推送任务
/**生产creep的任务
 * 1. 推送者必须要有id，意味着不能使用room推送生产任务
 */
function publishSpawnTask({ taskID, taskType, publisherID, roomName = null, taskParams = {}, isUrgent = false }) {
    if (!roomName) roomName = Game.getObjectById(publisherID).pos.roomName
    let publishObj = Game.getObjectById(publisherID)
    let taskDeta = {
        taskID: taskID,
        taskType: taskType,
        publisherID: publisherID,
        roomName: roomName,
        taskParams: taskParams,
        isUrgent: isUrgent
    }
    if (publishObj) {
        Memory.rooms[roomName]['structure'][publishObj.structureType][publisherID].publishTask.push(taskManager.addTask(taskDeta))
    } else {
        // 不存在对象，则说明是room自检后发布的任务
        Memory.rooms[roomName]['info'].publishTask.push(taskManager.addTask(taskDeta))
    }
}
/**资源需求任务 */
function pushNeedResourceTask(publishObj, resourceList, params = {}) {
    let { taskID = null, isUrgent = false } = params
    publishObj = objIDToObj(publishObj)
    let roomName = publishObj.pos.roomName
    let publisherID = publishObj.id
    Object.keys(resourceList).map(resource => {
        if (!taskID) taskID = `${publishObj.structureType}需求${resource}类型资源,数量为:${resourceList[resource]}`
        let taskDeta = {
            taskID: taskID,
            taskType: taskType.needResource,
            publisherID: publisherID,
            roomName: roomName,
            taskParams: {
                resource: resource,
                count: resourceList[resource]
            },
            isUrgent: isUrgent
        }
        Memory.rooms[roomName]['structure'][publishObj.structureType][publisherID].publishTask.push(taskManager.addTask(taskDeta))
    })
}
/**房间推送建筑任务 */
function pushBuildTask(room, targetID, params = {}) {
    let { taskID = null, isUrgent = false } = params
    if (targetID.length == 0) return
    room = roomNameToObj(room)
    taskID = taskID || `${room.name}存在${room.memory.autoBuild.buildAmount}点工程量,需要建筑工`
    let taskDeta = {
        taskID: taskID,
        taskType: taskType.build,
        publisherID: null,
        roomName: room.name,
        taskParams: {
            targetID: targetID
        },
        isUrgent: isUrgent
    }
    Memory.rooms[room.name]['info'].publishTask.push(taskManager.addTask(taskDeta))
}
/**推送维修任务 */
function pushRepaireTask(room, targetObj, params = {}) {
    const { isUrgent = false } = params
    room = roomNameToObj(room)
    targetObj = objIDToObj(targetObj)
    let taskID = `${room.name}的${targetObj.name ? targetObj.name : targetObj.id}需要维修`
    let taskDeta = {
        taskID: taskID,
        taskType: taskType.repaire,
        publisherID: targetObj.id,
        roomName: room.name,
        taskParams: {
            targetID: [targetObj.id]
        },
        isUrgent: isUrgent
    }
    Memory.rooms[targetObj.pos.roomName]['structure'][targetObj.structureType][targetObj.id].publishTask.push(taskManager.addTask(taskDeta))

}
// #endregion
export default taskManager
export {
    publishSpawnTask,
    pushNeedResourceTask,
    pushBuildTask,
    pushRepaireTask,
}